/**
 * 核心弹幕渲染器
 * 独立的、可复用的弹幕渲染引擎
 */

import type {
  BarrageItem,
  BarrageConfig,
  BarrageAPI,
  BarrageRendererOptions,
  ActiveBarrage,
  BarrageTrack,
  DetectionArea
} from '../types'
import type { PoseDetectionState } from '../features/mediapipe-pose/PoseDetectionService.ts'
import { ConfigManager } from './managers/ConfigManager'
import { EventManager } from './managers/EventManager'
import { VideoHelper } from './utils/VideoHelper'
import { BarrageDrawer } from './renderers/BarrageDrawer'
import { FrameRenderer } from './renderers/FrameRenderer'
import { FeatureIntegration } from './integrations/FeatureIntegration'

export class BarrageRenderer implements BarrageAPI {
  private container: HTMLElement
  private video?: HTMLVideoElement
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D
  
  // 管理器
  private configManager: ConfigManager
  private eventManager: EventManager
  private videoHelper: VideoHelper
  private barrageDrawer: BarrageDrawer
  private frameRenderer: FrameRenderer
  private featureIntegration: FeatureIntegration

  private tracks: BarrageTrack[] = []
  private activeBarrages: ActiveBarrage[] = []
  private barrageIdMap: Map<string, ActiveBarrage> = new Map()
  private barrageQueue: BarrageItem[] = [] // 弹幕队列
  private isDestroyed = false

  // 检测相关
  private detectionAreas: DetectionArea[] = []
  private resizeObserver?: ResizeObserver
  private videoEventHandlers: { event: string; handler: () => void }[] = []
  
  // 性能优化相关
  private detectionCache: Map<number, DetectionArea[]> = new Map()
  private cacheMaxSize = 50 // 缓存最大条目数
  private performanceMode = false // 性能模式


  constructor(options: BarrageRendererOptions) {
    this.container = options.container
    this.video = options.video
    
    // 初始化管理器
    this.configManager = new ConfigManager(options.config)
    this.eventManager = new EventManager(options.events)
    this.videoHelper = new VideoHelper(this.container, this.video)

    const config = this.configManager.getConfig()

    // 创建canvas
    this.canvas = document.createElement('canvas')
    this.canvas.className = `barrage-canvas ${config.className}`
    Object.assign(this.canvas.style, {
      position: 'absolute',
      top: '0',
      left: '0',
      pointerEvents: 'none',
      zIndex: '1000',
      ...config.style
    })

    const ctx = this.canvas.getContext('2d')
    if (!ctx) {
      throw new Error('无法创建Canvas上下文')
    }
    this.ctx = ctx

    this.container.appendChild(this.canvas)
    
    // 初始化渲染器和集成器
    this.barrageDrawer = new BarrageDrawer(this.ctx, this.canvas, this.videoHelper, this.video)
    this.featureIntegration = new FeatureIntegration(config.debug)
    this.featureIntegration.initVisualizer(this.ctx)
    this.featureIntegration.setVideo(this.video || null)
    
    // 初始化帧渲染器
    this.frameRenderer = new FrameRenderer({
      video: this.video,
      barrageDrawer: this.barrageDrawer,
      featureIntegration: this.featureIntegration,
      callbacks: {
        onRemoveBarrage: (id: string) => this.remove(id),
        onRenderDebug: () => this.renderDebugInfo(),
        getActiveBarrages: () => this.activeBarrages,
        getConfig: () => this.config
      }
    })
    
    this.initializeTracks()
    this.setupCanvas()
    this.setupResizeObserver()
    this.featureIntegration.setupPoseDetection(config.faceDetection || false)
    
    this.frameRenderer.start()
  }

  /** 获取当前配置（便捷方法） */
  private get config(): Required<BarrageConfig> {
    return this.configManager.getConfig()
  }

  /** 添加弹幕 */
  add(barrage: Omit<BarrageItem, 'id'>): string {
    const id = this.generateId()
    const barrageItem: BarrageItem = { id, ...barrage }
    
    // 检查是否达到最大显示数量
    const maxDisplayCount = (this.config as any).maxDisplayCount || this.config.maxBarrages
    if (this.activeBarrages.length >= maxDisplayCount) {
      // 添加到队列中等待
      this.barrageQueue.push(barrageItem)
      if (this.config.debug) {
        console.log('弹幕已加入队列:', barrageItem.text, '队列长度:', this.barrageQueue.length)
      }
      return id
    }

    return this.addFromQueue(barrageItem) || id
  }

  private addFromQueue(barrageItem: BarrageItem): string | null {
    // 检查视频播放状态和时间
    if (!this.shouldShowBarrage(barrageItem)) {
      // 如果时间未到或视频未播放，保持在队列中
      if (!this.barrageQueue.find(item => item.id === barrageItem.id)) {
        this.barrageQueue.push(barrageItem)
      }
      if (this.config.debug) {
        console.log('弹幕时间未到或视频未播放，保持在队列中:', barrageItem.text, '时间:', barrageItem.time)
      }
      return null
    }
    
    const track = this.findAvailableTrack()
    if (!track) {
      // 如果没有可用轨道，保持在队列中
      if (!this.barrageQueue.find(item => item.id === barrageItem.id)) {
        this.barrageQueue.push(barrageItem)
      }
      if (this.config.debug) {
        console.warn('没有可用轨道，弹幕保持在队列中:', barrageItem.text)
      }
      return null
    }

    const activeBarrage = this.createActiveBarrage(barrageItem, track)
    this.activeBarrages.push(activeBarrage)
    this.barrageIdMap.set(barrageItem.id, activeBarrage)
    
    track.occupied = true
    track.lastUsed = Date.now()

    this.eventManager.onAdd(barrageItem)
    this.updateCapacity()

    if (this.config.debug) {
      console.log('添加弹幕:', barrageItem.text, '轨道:', track.index)
    }

    return barrageItem.id
  }

  /** 处理弹幕队列 */
  private processQueue(): void {
    const maxDisplayCount = (this.config as any).maxDisplayCount || this.config.maxBarrages
    
    // 🔥 智能清理：如果超出容量120%，清理最早的弹幕
    if (this.activeBarrages.length > maxDisplayCount * 1.2) {
      this.smartCleanup(maxDisplayCount)
    }
    
    while (this.barrageQueue.length > 0 && this.activeBarrages.length < maxDisplayCount) {
      const nextBarrage = this.barrageQueue.shift()
      if (nextBarrage) {
        const result = this.addFromQueue(nextBarrage)
        if (!result) {
          // 如果添加失败，重新放回队列开头
          this.barrageQueue.unshift(nextBarrage)
          break
        }
      }
    }
  }

  /**
   * 🎯 智能清理策略：超量时自动清理最早的弹幕
   * 确保内存可控，防止弹幕堆积
   */
  private smartCleanup(targetCount: number): void {
    const excessCount = this.activeBarrages.length - targetCount
    if (excessCount <= 0) return

    // 按创建时间排序，清理最早的弹幕
    const sortedBarrages = [...this.activeBarrages]
      .sort((a, b) => (a.time || 0) - (b.time || 0))
    
    const toCleanup = sortedBarrages.slice(0, Math.min(excessCount, 10)) // 每次最多清理10条
    
    toCleanup.forEach(barrage => {
      this.remove(barrage.id)
    })
  }

  /** 获取队列状态 */
  getQueueStatus(): { queueLength: number; activeCount: number; maxCount: number } {
    const maxDisplayCount = (this.config as any).maxDisplayCount || this.config.maxBarrages
    return {
      queueLength: this.barrageQueue.length,
      activeCount: this.activeBarrages.length,
      maxCount: maxDisplayCount
    }
  }

  /** 移除弹幕 */
  remove(id: string): boolean {
    const barrage = this.barrageIdMap.get(id)
    if (!barrage) return false

    const index = this.activeBarrages.indexOf(barrage)
    if (index >= 0) {
      this.activeBarrages.splice(index, 1)
      this.barrageIdMap.delete(id)
      
      // 释放轨道
      const track = this.tracks[barrage.track]
      if (track) {
        track.occupied = false
      }

      this.eventManager.onRemove(barrage)
      this.updateCapacity()

      // 尝试从队列中添加下一个弹幕
      this.processQueue()

      if (this.config.debug) {
        console.log('移除弹幕:', barrage.text)
      }

      return true
    }

    return false
  }

  /** 清空所有弹幕 */
  clear(): void {
    const removedBarrages = [...this.activeBarrages]
    this.activeBarrages = []
    this.barrageIdMap.clear()
    this.barrageQueue = [] // 清空队列
    
    // 释放所有轨道
    this.tracks.forEach(track => {
      track.occupied = false
    })

    removedBarrages.forEach(barrage => {
      this.eventManager.onRemove(barrage)
    })

    this.updateCapacity()
    this.clearCanvas() // 强制清理canvas

    if (this.config.debug) {
      console.log('清空所有弹幕')
    }
  }

  /** 强制清理canvas内容 */
  clearCanvas(): void {
    if (this.ctx) {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
    }
  }


  /** 检查弹幕是否应该显示 */
  private shouldShowBarrage(barrageItem: BarrageItem): boolean {
    // 检查视频是否存在
    if (!this.video) {
      return false
    }
    
    // 检查视频是否已加载
    if (this.video.readyState < 2) { // HAVE_CURRENT_DATA
      return false
    }
    
    // 检查视频是否正在播放或已暂停但有播放时间
    if (this.video.paused && this.video.currentTime === 0) {
      return false
    }
    
    // 检查弹幕时间是否到了
    const currentTime = this.video.currentTime
    const tolerance = 0.5 // 0.5秒的容差
    
    return (barrageItem.time ?? 0) <= currentTime + tolerance
  }

  /** 暂停弹幕 */
  pause(): void {
    this.frameRenderer.pause()
    if (this.config.debug) {
      console.log('暂停弹幕')
    }
  }

  /** 恢复弹幕 */
  resume(): void {
    this.frameRenderer.resume()
    if (this.config.debug) {
      console.log('恢复弹幕')
    }
  }

  /** 获取活跃弹幕数量 */
  getActiveCount(): number {
    return this.activeBarrages.length
  }

  /** 获取最大容量 */
  getMaxCapacity(): number {
    return this.config.maxBarrages
  }

  /** 更新配置 */
  updateConfig(newConfig: Partial<BarrageConfig>): void {
    const oldConfig = this.configManager.getConfig()
    this.configManager.updateConfig(newConfig)
    const config = this.configManager.getConfig()

    // 🆕 如果字体大小改变，更新现有弹幕的文本宽度
    if (newConfig.fontSize !== undefined && newConfig.fontSize !== oldConfig.fontSize) {
      this.activeBarrages.forEach(barrage => {
        // 更新弹幕的字体大小
        barrage.fontSize = newConfig.fontSize!
        // 重新计算文本宽度（字体大小改变会影响宽度）
        barrage.width = this.measureTextWidth(barrage.text, newConfig.fontSize!)
      })
      
      if (config.debug) {
        console.log(`🔤 字体大小更新: ${oldConfig.fontSize} → ${newConfig.fontSize}, 已更新 ${this.activeBarrages.length} 条现有弹幕`)
      }
    }

    // 🆕 如果透明度改变，更新现有弹幕的透明度（可选，因为渲染时会优先使用最新配置）
    if (newConfig.opacity !== undefined && newConfig.opacity !== oldConfig.opacity) {
      this.activeBarrages.forEach(barrage => {
        barrage.opacity = newConfig.opacity!
      })
      
      if (config.debug) {
        console.log(`🌟 透明度更新: ${oldConfig.opacity} → ${newConfig.opacity}, 已更新 ${this.activeBarrages.length} 条现有弹幕`)
      }
    }

    // 🚀 如果速度改变，更新现有弹幕的速度（关键修复：防止重叠）
    if (newConfig.speed !== undefined && newConfig.speed !== oldConfig.speed) {
      this.activeBarrages.forEach(barrage => {
        barrage.speed = newConfig.speed!
      })
      
      console.log(`⚡ 速度更新: ${oldConfig.speed} → ${newConfig.speed}px/s, 已更新 ${this.activeBarrages.length} 条现有弹幕`)
      
      // 🔧 额外优化：重新调整弹幕间距，防止速度变化导致的潜在重叠
      this.adjustBarrageSpacing(newConfig.speed!)
      
      if (config.debug) {
        console.log(`🔧 防重叠修复: 所有现有弹幕速度已同步更新，间距已重新调整`)
      }
    }

    // 如果轨道配置改变，重新初始化轨道
    if (oldConfig.trackCount !== config.trackCount || 
        oldConfig.trackHeight !== config.trackHeight) {
      this.initializeTracks()
    }

    // 更新canvas样式
    if (newConfig.style) {
      Object.assign(this.canvas.style, newConfig.style)
    }

    if (config.debug) {
      console.log('更新配置:', newConfig)
    }
  }

  /** 销毁组件 */
  destroy(): void {
    if (this.isDestroyed) return

    this.isDestroyed = true
    this.frameRenderer.destroy()
    this.resizeObserver?.disconnect()
    
    // 清理视频事件监听器
    if (this.video) {
      this.videoEventHandlers.forEach(({ event, handler }) => {
        this.video!.removeEventListener(event, handler)
      })
      this.videoEventHandlers = []
    }
    
    if (this.container.contains(this.canvas)) {
      this.container.removeChild(this.canvas)
    }

    this.clear()

    // 销毁功能集成器
    this.featureIntegration.destroy()

    if (this.config.debug) {
      console.log('销毁弹幕渲染器')
    }
  }

  /** 设置检测区域 */
  setDetectionAreas(areas: DetectionArea[]): void {
    this.detectionAreas = areas
  }

  /** 启用/禁用性能模式 */
  setPerformanceMode(enabled: boolean): void {
    this.performanceMode = enabled
    if (enabled) {
      this.featureIntegration.setDetectionInterval(200) // 性能模式下降低检测频率
      // console.log('🚀 性能模式已启用：降低检测频率，启用缓存')
    } else {
      this.featureIntegration.setDetectionInterval(100)
      // console.log('🎯 精确模式已启用：提高检测频率')
    }
  }


  // /** 智能检测区域更新 */
  // private updateDetectionAreas(currentTime: number): DetectionArea[] {
  //   // 如果距离上次检测时间太短，使用缓存
  //   if (currentTime - this.lastDetectionTime < this.detectionInterval) {
  //     const cached = this.getCachedDetection(currentTime)
  //     if (cached) {
  //       return cached
  //     }
  //   }

  //   // 执行新的检测（这里模拟检测过程）
  //   const newAreas = this.performDetection()
    
  //   // 缓存结果
  //   this.cacheDetection(currentTime, newAreas)
  //   this.lastDetectionTime = currentTime
    
  //   return newAreas
  // }



  /** 获取备用模式状态 */
  isFallbackMode(): boolean {
    return this.frameRenderer.isFallbackMode()
  }

  /** 重置检测状态 */
  resetDetectionState(): void {
    this.frameRenderer.setFallbackMode(false)
    this.detectionCache.clear()
    // console.log('🔄 检测状态已重置')
  }

  /** 切换蒙版模式 */
  toggleMaskMode(enabled?: boolean): boolean {
    return this.featureIntegration.toggleMaskMode(enabled)
  }

  /** 设置纯蒙版透明度 */
  setPureMaskOpacity(opacity: number): void {
    this.featureIntegration.setPureMaskOpacity(opacity)
  }


  /** 私有方法 */
  private generateId(): string {
    return `barrage_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  /**
   * 测量文本宽度
   */
  private measureTextWidth(text: string, fontSize: number): number {
    this.ctx.font = `bold ${fontSize}px sans-serif`
    return this.ctx.measureText(text).width
  }

  private initializeTracks(): void {
    // 🆕 保存现有弹幕的轨道分配信息
    const existingBarragesByTrack = new Map<number, any[]>()
    if (this.tracks.length > 0) {
      this.tracks.forEach(track => {
        if (track.activeBarrages && track.activeBarrages.length > 0) {
          existingBarragesByTrack.set(track.index, [...track.activeBarrages])
        }
      })
    }

    this.tracks = []
    const startY = 50 // 顶部边距
    
    for (let i = 0; i < this.config.trackCount; i++) {
      this.tracks.push({
        index: i,
        y: startY + i * this.config.trackHeight,
        height: this.config.trackHeight,
        occupied: false,
        lastUsed: 0,
        // 🆕 恢复该轨道上的现有弹幕（如果有的话）
        activeBarrages: existingBarragesByTrack.get(i) || [],
        lastBarrageTime: 0
      })
    }

    // 🆕 更新现有弹幕的 Y 坐标以适应新的轨道布局
    this.activeBarrages.forEach(barrage => {
      if (barrage.track < this.tracks.length) {
        const track = this.tracks[barrage.track]
        const fontSize = barrage.fontSize || this.config.fontSize || 20
        barrage.y = track.y + (track.height - fontSize) / 2
      }
    })

    if (this.config.debug) {
      console.log(`🔄 重新初始化 ${this.config.trackCount} 条轨道，保留了 ${this.activeBarrages.length} 条现有弹幕`)
    }
  }

  private findAvailableTrack(): BarrageTrack | null {
    if (!this.config.avoidOverlap) {
      // 如果不需要避免重叠，使用轮询分配确保所有轨道都被使用
      return this.findTrackByRoundRobin()
    }

    // 根据填充模式选择不同的分配策略
    switch (this.config.trackFillMode) {
      case 'maximum':
        return this.findTrackForMaximumFill()
      case 'dense':
        return this.findTrackForDenseFill()
      case 'sparse':
        return this.findTrackForSparseFill()
      default:
        return this.findTrackForNormalFill()
    }
  }

  private findTrackByRoundRobin(): BarrageTrack | null {
    // 轮询分配，确保所有轨道都被使用
    const startIndex = Date.now() % this.tracks.length
    for (let i = 0; i < this.tracks.length; i++) {
      const trackIndex = (startIndex + i) % this.tracks.length
      const track = this.tracks[trackIndex]
      if (this.canPlaceBarrageOnTrack(track)) {
        return track
      }
    }
    return null
  }

  private findTrackForMaximumFill(): BarrageTrack | null {
    // 最大化填充：使用最小间距，优先填满所有轨道
    const originalMinSpace = this.config.minSpace
    this.config.minSpace = 2 // 临时设置最小间距
    
    // 优先选择空轨道
    const emptyTracks = this.tracks.filter(track => 
      this.activeBarrages.filter(b => b.track === track.index).length === 0
    )
    
    if (emptyTracks.length > 0) {
      this.config.minSpace = originalMinSpace
      return emptyTracks[0]
    }

    // 如果没有空轨道，选择最有空间的轨道
    for (const track of this.tracks) {
      if (this.canPlaceBarrageOnTrack(track)) {
        this.config.minSpace = originalMinSpace
        return track
      }
    }

    this.config.minSpace = originalMinSpace
    return null
  }

  private findTrackForDenseFill(): BarrageTrack | null {
    // 🆕 密集填充：轮流使用所有轨道，确保均匀分布
    // 按弹幕数量从少到多排序，优先使用弹幕少的轨道
    const tracksByLoad = this.tracks
      .map(track => ({
        track,
        count: this.activeBarrages.filter(b => b.track === track.index).length
      }))
      .sort((a, b) => a.count - b.count) // 弹幕少的在前
    
    // 从弹幕最少的轨道开始尝试
    for (const { track } of tracksByLoad) {
      if (this.canPlaceBarrageOnTrack(track)) {
        return track
      }
    }

    return null
  }

  private findTrackForSparseFill(): BarrageTrack | null {
    // 稀疏填充：优先使用空轨道，保持较大间距
    const emptyTracks = this.tracks.filter(track => 
      this.activeBarrages.filter(b => b.track === track.index).length === 0
    )
    
    if (emptyTracks.length > 0) {
      return emptyTracks[0]
    }

    // 如果没有空轨道，检查是否有足够空间
    for (const track of this.tracks) {
      if (this.canPlaceBarrageOnTrack(track)) {
        return track
      }
    }

    return null
  }

  private findTrackForNormalFill(): BarrageTrack | null {
    // 正常填充：平衡空轨道和有弹幕的轨道
    const emptyTracks = this.tracks.filter(track => 
      this.activeBarrages.filter(b => b.track === track.index).length === 0
    )
    
    // 优先使用空轨道
    if (emptyTracks.length > 0) {
      return emptyTracks[0]
    }

    // 然后检查有弹幕的轨道
    for (const track of this.tracks) {
      if (this.canPlaceBarrageOnTrack(track)) {
        return track
      }
    }

    return null
  }

  private canPlaceBarrageOnTrack(track: BarrageTrack): boolean {
    // 获取该轨道上的所有活跃弹幕
    const barragesOnTrack = this.activeBarrages.filter(barrage => barrage.track === track.index)
    
    if (barragesOnTrack.length === 0) {
      return true // 轨道为空，可以放置
    }

    // 根据填充模式调整间距要求
    let minSpace = this.config.minSpace || 10
    switch (this.config.trackFillMode) {
      case 'maximum':
        minSpace = 2
        break
      case 'dense':
        minSpace = Math.max(2, minSpace * 0.5)
        break
      case 'sparse':
        minSpace = minSpace * 1.5
        break
      default:
        // normal模式使用默认间距
        break
    }

    // 检查最右侧的弹幕是否有足够的间距
    const rightmostBarrage = barragesOnTrack.reduce((rightmost, current) => 
      current.x > rightmost.x ? current : rightmost
    )

    // 考虑弹幕的移动速度，预测未来位置
    const timeElapsed = Date.now() - rightmostBarrage.createdAt
    const predictedX = rightmostBarrage.x - (rightmostBarrage.speed * timeElapsed / 1000)

    // 计算所需的空间
    const requiredSpace = rightmostBarrage.width + minSpace

    // 检查是否有足够的空间放置新弹幕
    const availableSpace = this.canvas.width - Math.max(rightmostBarrage.x, predictedX)
    
    // 对于最大化模式，更宽松的空间检查
    if (this.config.trackFillMode === 'maximum') {
      return availableSpace >= requiredSpace * 0.8
    }
    
    return availableSpace >= requiredSpace
  }

  private createActiveBarrage(barrage: BarrageItem, track: BarrageTrack): ActiveBarrage {
    const fontSize = barrage.fontSize || this.config.fontSize
    const text = barrage.text
    
    // 测量文本宽度
    this.ctx.font = `bold ${fontSize}px sans-serif`
    const width = this.ctx.measureText(text).width

    return {
      ...barrage,
      x: this.canvas.width,
      y: track.y,
      width,
      track: track.index,
      speed: this.config.speed,
      opacity: this.config.opacity,
      fontSize,
      color: barrage.color || '#FFFFFF',
      createdAt: Date.now()
    }
  }

  private setupCanvas(): void {
    const videoRect = this.videoHelper.getVideoDisplayRect()
    const dpr = window.devicePixelRatio || 1
    
    // 设置Canvas位置和大小以匹配视频的实际显示区域
    this.canvas.style.left = `${videoRect.left}px`
    this.canvas.style.top = `${videoRect.top}px`
    this.canvas.style.width = `${videoRect.width}px`
    this.canvas.style.height = `${videoRect.height}px`
    
    this.canvas.width = Math.floor(videoRect.width * dpr)
    this.canvas.height = Math.floor(videoRect.height * dpr)
    
    this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
    this.ctx.textBaseline = 'top'
  }

  private setupResizeObserver(): void {
    this.resizeObserver = new ResizeObserver(() => {
      this.setupCanvas()
      this.initializeTracks()
    })
    this.resizeObserver.observe(this.container)

    // 监听视频加载事件，当视频尺寸变化时重新计算弹幕区域
    if (this.video) {
      const handleVideoResize = () => {
        this.setupCanvas()
        this.initializeTracks()
      }

      const events = ['loadedmetadata', 'resize', 'loadeddata']
      events.forEach(eventName => {
        this.video!.addEventListener(eventName, handleVideoResize)
        this.videoEventHandlers.push({ event: eventName, handler: handleVideoResize })
      })
    }
  }


  private renderDebugInfo(): void {
    this.detectionAreas = this.frameRenderer.getDetectionAreas()
    this.barrageDrawer.renderDebugInfo(
      this.activeBarrages,
      this.barrageQueue.length,
      this.config,
      this.tracks,
      this.detectionAreas,
      this.performanceMode,
      this.frameRenderer.isFallbackMode(),
      this.detectionCache.size,
      this.cacheMaxSize,
      this.featureIntegration.getPureMaskController()
    )
  }

  private updateCapacity(): void {
    this.eventManager.onCapacityChange(this.getActiveCount(), this.getMaxCapacity())
  }

  getPoseDetectionState(): PoseDetectionState {
    return this.featureIntegration.getPoseDetectionState()
  }

  reloadPoseDetection(): void {
    this.featureIntegration.reloadPoseDetection()
  }

  /**
   * 🔧 调整弹幕间距，防止速度变更导致重叠
   */
  private adjustBarrageSpacing(_newSpeed: number): void {
    const minGap = this.configManager.getConfig().minBarrageGap || 20
    
    // 按轨道分组处理
    const barragesByTrack = new Map<number, ActiveBarrage[]>()
    
    this.activeBarrages.forEach(barrage => {
      if (!barragesByTrack.has(barrage.track)) {
        barragesByTrack.set(barrage.track, [])
      }
      barragesByTrack.get(barrage.track)!.push(barrage)
    })
    
    // 对每个轨道的弹幕进行间距调整
    barragesByTrack.forEach(barrages => {
      // 按X坐标排序（从右到左）
      barrages.sort((a, b) => b.x - a.x)
      
      // 调整间距
      for (let i = 1; i < barrages.length; i++) {
        const current = barrages[i]
        const previous = barrages[i - 1]
        
        const requiredDistance = previous.width + minGap
        const actualDistance = previous.x - (current.x + current.width)
        
        // 如果间距不足，调整当前弹幕位置
        if (actualDistance < 0) {
          current.x = previous.x - requiredDistance
          console.log(`🔧 调整弹幕间距: 弹幕 ${current.id} 位置调整到 ${current.x}`)
        }
      }
    })
  }
}
